{%- import "method-macro.cc.j2" as method_macro %}

{%- set class_name = "%sTestConsumer"|format(interface.mojom_name) %}

class {{class_name}}
  : public ::ash::cros_healthd::connectivity::DataGeneratorInterface<
      ::mojo::PendingReceiver<{{interface.mojom_name}}>> {
 public:
  {{class_name}}(const {{class_name}}&) = delete;
  {{class_name}}& operator=(const {{class_name}}&) = delete;
  virtual ~{{class_name}}() = default;

  static std::unique_ptr<{{class_name}}> Create(
    ::ash::cros_healthd::connectivity::Context* context);

 public:
  void Bind(::mojo::PendingRemote<{{interface.mojom_name}}> remote);

  // Checks the interface. The callback will be fulfilled with |true| if the
  // interface passed the test. This is non-blocking but synchronize. The caller
  // needs to wait until the callback being fulfilled to perform the next call.
  using CheckCallback = base::OnceCallback<void(bool)>;
  void Check(CheckCallback callback);
  // Returns the closure to check the interface.
  base::OnceCallback<void(CheckCallback)> CheckClosure();

  // DataGeneratorInterface overrides.
  ::mojo::PendingReceiver<{{interface.mojom_name}}> Generate() override;
  bool HasNext() override { return has_next_; }

 protected:
  explicit {{
    class_name}}(::ash::cros_healthd::connectivity::Context* context);

 private:
  void SetCheckResult(CheckCallback callback, bool res);

{#- Methods are splitted into multiple stages to be used as callback. #}
{%- for method in interface.methods %}
  void CheckStep1__{{method.mojom_name}}(CheckCallback callback);
  void CheckStep2__{{method.mojom_name}}(CheckCallback callback);
  void CheckStep3__{{method.mojom_name}}(CheckCallback callback);
{%  endfor %}

 private:
  ::ash::cros_healthd::connectivity::Context* context_;

  bool has_next_ = true;
  // Used to cached the check result.
  bool check_reentry_status_ = false;
  absl::optional<bool> check_result_;

  ::mojo::Remote<{{interface.mojom_name}}> remote_;

{%- for method in interface.methods %}
  {{method_macro.declare_data_generator(
      method.mojom_name ~ "__", method.parameters)}}
{%- endfor %}

  // Must be the last member of the class.
  base::WeakPtrFactory<{{class_name}}> weak_factory_{this};
};
